export default {
	name: "fileManager",
	setup(props) {
		const router = VueRouter.useRouter();
		const route = VueRouter.useRoute();
		const searchText = ref('')
		const currentPage = ref(1)
		const pageSize = ref(15)
		const total = ref(0)
		const files = ref([])
		const selectedFiles = ref([])
		const loading = ref(false)
		const showUploadDialog = ref(false);
		const qrDialogVisible = ref(false);
		const ewmurl = ref(false);
		const operationDialog = ref({
			visible: false,
			type: '',
			file: null
		})
		const currentPath = ref('') // 当前路径
		const breadcrumb = ref([]) // 面包屑导航
        const textEditDialog = ref({
            isedit: false,
            content: '',
            file: null
        })
        const previewVisible = ref(false);
        // 定义可编辑文件类型列表
        const editableExtensions = ['txt', 'php', 'js', 'html', 'css', 'py', 'java', 'xml', 'json'];
        const isEditable = (ext) => editableExtensions.includes(ext);
        
		// 文件类型图标映射
		const fileIcons = {
			'folder': 'Folder', // 文件夹图标
			'txt': 'Document',
			'pdf': 'Document',
			'doc': 'Document',
			'docx': 'Document',
			'xls': 'DocumentDelete',
			'xlsx': 'DocumentDelete',
			'ppt': 'Document',
			'pptx': 'Document',
			'jpg': 'Picture',
			'jpeg': 'Picture',
			'png': 'Picture',
			'gif': 'Picture',
			'bmp': 'Picture',
			'svg': 'Picture',
			'mp4': 'VideoPlay',
			'avi': 'VideoPlay',
			'mkv': 'VideoPlay',
			'mov': 'VideoPlay',
			'mp3': 'Audio',
			'wav': 'Audio',
			'flac': 'Audio',
			'zip': 'Dish',
			'rar': 'Dish',
			'tar': 'Dish',
			'7z': 'Dish',
            'php': 'Tickets',
            'js': 'Tickets',
            'html': 'Tickets',
            'css': 'Tickets',
            'py': 'Tickets',
            'java': 'Tickets',
            'json': 'Tickets',
            'xml': 'Tickets',
			'default': 'Document' // 默认图标
		};

		const getFileIcon = (row) => {
			return row.isDir ? 'folder' : (fileIcons[row.ext] || fileIcons.default);
		};

		const isZipFile = (file) => file.ext === 'zip';

		// 文件操作处理
		const handleCommand = async (command, file) => {
		    if(command == 'delete') {
                handleDelete(file);
		    }else{
    			operationDialog.value = {
    				visible: true,
    				type: command,
    				file: file
    			}
    			await nextTick(); // 确保DOM更新
		    }
		}
		
        // 分享文件复制链接
        const getshare = async (params) => {
            const res = await share(params);
            if (!res?.url) {
                return ElMessage.error('分享失败');
            }
            ewmurl.value = res.url;
            qrDialogVisible.value = true;
        };
        
        const copyCode = async () => {
            if(!ewmurl.value) return ElMessage.error('分享链接为空');
            try {
                await navigator.clipboard.writeText(ewmurl.value);
                ElMessage.success('已复制链接');
            } catch (err) {
                ElMessage.error('复制失败，请手动复制');
            }
        }

		// 确认文件操作
		const handleOperationConfirm = async (params) => {
			try {
				switch (operationDialog.value.type) {
					case 'rename':
						await rename(params)
						break
					case 'move':
						await filemove(params)
						break
					case 'copy':
						await filecopy(params)
						break
					case 'zip':
					    if(selectedFiles.value.length == 0) {
        			        return ElMessage.error('请先选择文件');
        			    }
        			    const files = selectedFiles.value.filter(v => v.fullPath).map(v => v.fullPath);
						await filezip({ files, ...params });
						break
					case 'unzip':
						await unzip(params)
						break
					case 'share':
						await getshare(params)
						break
				}
				loadFiles()
				ElMessage.success('操作成功')
			} catch (error) {
				ElMessage.error('操作失败: ' + error.message)
			}
		}

		// 多选处理
		const handleSelectionChange = (selection) => {
			selectedFiles.value = selection
		}

		// 批量压缩
		const handleBatchCommand = () => {
		    if(selectedFiles.value.length == 0) {
		        return ElMessage.error('请先选择文件');
		    }
			operationDialog.value = {
				visible: true,
				type: 'zip',
			}
		}
		
		//批量删除
		const handleBatchDelete = async () => {
		    if(selectedFiles.value.length == 0) {
		        return ElMessage.error('请先选择文件/目录');
		    }
            await ElMessageBox.confirm(`确定删除 ${selectedFiles.value.length}个文件/目录？`, '警告', {
                type: 'warning'
            })
            for (const file of selectedFiles.value) {
                await delfile({ path: file.fullPath })
            }
            ElMessage.success(`已删除 ${selectedFiles.value.length}个文件/目录`);
            await loadFiles();
		}

		// 文件类型颜色
		const getFileColor = (file) => {
			if (file.isDir) return '#409EFF'
			const typeColors = {
				image: '#FF69B4',
				video: '#FFA500',
				pdf: '#FF0000',
				text: '#67C23A',
				default: '#909399'
			}
			return typeColors[file.type] || typeColors.default
		}

		// 加载文件列表
		const loadFiles = async () => {
			const res = await filelist({
				path: currentPath.value,
				keyword: searchText.value,
				page: currentPage.value,
				pageSize: pageSize.value
			});
			files.value = res.items;
			total.value = res.total;
			updateBreadcrumb()
		}

		// 更新面包屑导航
		const updateBreadcrumb = () => {
			const paths = currentPath.value.split('/').filter(p => p)
			breadcrumb.value = paths.map((p, index) => ({
				name: p,
				path: paths.slice(0, index + 1).join('/')
			}))
		}

		// 进入目录
		const enterDirectory = (path) => {
			currentPath.value = path
			loadFiles()
		}

		// 返回上级
		const goBack = () => {
			const paths = currentPath.value.split('/')
			paths.pop()
			currentPath.value = paths.join('/')
			loadFiles()
		}
		
		//格式化文本
        const formatTextContent = (text) => {
            return text.split(/\n+/).map(paragraph => {
                // 清除首尾空白并过滤空段落
                const cleaned = paragraph.replace(/^[\s　]+|[\s　]+$/g, '')
                return cleaned ? `<p class="text-content">${cleaned}</p>` : ''
            }).join('')
        }

		// 文件预览
        const handlePreview = async (file) => {
            if (file.isDir) return enterDirectory(file.fullPath);
            const res = await previewfile({ path: file.fullPath });
            // 定义禁止下载的文件类型（示例列表，可按需扩展）
            const forbiddenExts = ['exe', 'bat', 'sh', 'jar', 'vbs', 'ps1', 'dll', 'scr', 'cmd'];
            const ext = file.ext.toLowerCase(); // 统一转为小写
            // 检查是否禁止下载的类型
            if (forbiddenExts.includes(ext)) {
                return ElMessage.error('出于安全考虑，此文件类型禁止下载');
            }
            if (['jpg', 'jpeg', 'png', 'gif', 'mp4', 'pdf'].includes(ext)) {
                textEditDialog.value = { isedit: false, content: res.url, file: file };
                previewVisible.value = true;
            } else if (isEditable(ext)) {
                textEditDialog.value = { isedit: false, content: res.content, file: file };
                previewVisible.value = true;
            } else {
                window.open(res.url); // 安全文件下载
            }
        }

		// 创建目录
        const handleCreateDir = async () => {
            const basePath = currentPath.value || ''
            const baseDir = basePath.endsWith('/') ? basePath : `${basePath}/`
            try {
                const { value } = await ElMessageBox.prompt(
                    '请输入文件夹名称',
                    '新建文件夹',
                    {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        inputPattern: /^[^\\/:*?"<>|]+$/, // 文件名合法性校验
                        inputErrorMessage: '名称包含非法字符（\\ / : * ? " < > |）'
                    }
                )
                await directory({path: baseDir, name: value});
                ElMessage.success('创建成功');
                loadFiles();
            } catch (e) {
                // 用户取消操作时不提示错误
                if (e !== 'cancel') {
                    ElMessage.error(e.message || '操作失败')
                }
            }
        }
        
        // 新建文件
        const handleCreateFile = async () => {
            const basePath = currentPath.value || '';
            const baseDir = basePath.endsWith('/') ? basePath : `${basePath}/`;
            // 定义一组危险后缀
            const dangerousExtensions = ['exe', 'bat', 'sh'];
            try {
                const { value } = await ElMessageBox.prompt(
                    '请输入文件名（包含扩展名，如aa.txt）',
                    '新建文件',
                    { inputPattern: /^[^\/*?"<>|]+\.\w+$/, inputErrorMessage: '文件名格式错误' }
                );
                let fileName = value.trim();
                // 检查文件名是否包含扩展名，如果没有，自动添加 .txt 后缀
                if (!fileName.includes('.')) {
                    fileName += '.txt';
                }
                // 获取文件名的扩展名
                const fileExtension = fileName.split('.').pop().toLowerCase();
                // 如果文件的扩展名是危险的，自动纠正为 .txt
                if (dangerousExtensions.includes(fileExtension)) {
                    fileName = fileName.replace(/\.\w+$/, '.txt');
                }
                await createfile({ path: baseDir, name: fileName });
                loadFiles();
                ElMessage.success('创建成功');
            } catch (e) {
                if (e !== 'cancel') ElMessage.error(e.message);
            }
        };

		// 文件上传成功处理
		const handleUploadSuccess = () => {
			loadFiles()
		}

		// 删除文件/目录
        const handleDelete = async (file) => {
            await ElMessageBox.confirm(`确定删除 ${file.name}？`, '警告', {
                type: 'warning'
            })
            await delfile({ path: file.fullPath })
            await loadFiles()
            ElMessage.success(`已删除 ${file.name}`)
        }

		const formatFileSize = (size) => {
			if (!size || isNaN(size)) return '0 B'; // 添加判断是否是有效数字
			const units = ['B', 'KB', 'MB', 'GB'];
			let i = 0;
			while (size >= 1024 && i < 3) {
				size /= 1024;
				i++;
			}
			return `${size.toFixed(1)} ${units[i]}`;
		};

        //文本编辑保存		
        const handleSaveText = async () => {
            try {
                await savetxt({
                    path: textEditDialog.value.file.fullPath,
                    content: textEditDialog.value.content
                })
                ElMessage.success('保存成功')
                textEditDialog.value.isedit = false
                loadFiles()
            } catch (error) {
                ElMessage.error(`保存失败: ${error.message}`)
            }
        }
        
        // 高亮代码方法
        const highlightCode = (content, lang = 'php') => {
            try {
                return hljs.highlight(content, { language: lang }).value;
            } catch {
                return hljs.highlightAuto(content).value;
            }
        }
		
		onMounted(() => {
		    loadFiles();
		    hljs.highlightAll();
		})

		return {
			searchText,
			currentPage,
			pageSize,
			files,
			total,
			currentPath,
			breadcrumb,
			fileIcons,
			formatFileSize,
			loadFiles,
			enterDirectory,
			goBack,
			handlePreview,
			handleCreateDir,
			handleDelete,
			handleUploadSuccess,
			loading,
			selectedFiles,
			operationDialog,
			handleCommand,
			handleOperationConfirm,
			handleSelectionChange,
			handleBatchCommand,
			handleBatchDelete,
			getFileColor,
			isZipFile,
			getFileIcon,
			showUploadDialog,
			getshare,
			handleCreateFile,
			formatTextContent,
			previewVisible,
			textEditDialog,
			handleSaveText,
			isEditable,
			editableExtensions,
			highlightCode,
			qrDialogVisible,
			ewmurl,
			copyCode
		};
	},

    template: `
	<div class="file-manager-container">
		<!-- 操作栏 -->
		<div class="action-bar">
			<el-row :gutter="20">
				<el-col :span="18">
					<el-button type="primary" @click="handleCreateDir" plain><el-icon><FolderAdd /></el-icon>新建文件夹</el-button>
					<el-button @click="handleCreateFile" plain><el-icon><DocumentAdd /></el-icon>新建文件</el-button>
					<el-button type="success" plain @click="showUploadDialog = true"><el-icon><Upload /></el-icon>上传文件</el-button>

					<el-button type="warning" plain @click="handleBatchDelete" :disabled="selectedFiles.length === 0">
						<el-icon><Delete /></el-icon>批量删除
					</el-button>
					<el-button type="info" plain @click="handleBatchCommand" :disabled="selectedFiles.length === 0">
						<el-icon><Dish /></el-icon>批量压缩
					</el-button>
				</el-col>
				<el-col :span="6">
					<el-input v-model="searchText" placeholder="搜索文件..." clearable @keyup.enter="loadFiles" class="search-input">
						<template #prefix><el-icon><Search /></el-icon></template>
					</el-input>
				</el-col>
			</el-row>
		</div>

		<!-- 面包屑导航 -->
		<el-breadcrumb separator="/" class="breadcrumb2">
			<el-breadcrumb-item @click="enterDirectory('')">
				<el-link type="primary"><el-icon size="18"><House /></el-icon> &nbsp;根目录</el-link>
			</el-breadcrumb-item>
			<el-breadcrumb-item v-for="item in breadcrumb" :key="item.path">
				<el-link type="primary" @click="enterDirectory(item.path)">{{ item.name }}</el-link>
			</el-breadcrumb-item>
		</el-breadcrumb>

		<!-- 文件表格 -->
		<el-table :data="files" style="width: 100%" @selection-change="handleSelectionChange" v-loading="loading" class="file-table" row-key="fullPath">
			<el-table-column type="selection" width="55" />
			<el-table-column prop="name" label="名称" min-width="300">
				<template #default="{ row }">
					<div class="file-item" @dblclick="handlePreview(row)">
						<el-icon class="file-icon" :color="getFileColor(row)">
							<component :is="getFileIcon(row)" />
						</el-icon>
						<el-link @click="handlePreview(row)" class="file-name">{{ row.name }}</el-link>
					</div>
				</template>
			</el-table-column>
			<el-table-column prop="type" label="类型" width="120">
				<template #default="{ row }">
					{{ row.isDir ? '文件夹' : row.ext }}
				</template>
			</el-table-column>
			<el-table-column prop="size" label="大小" width="120" :formatter="formatFileSize">
			    <template #default="{ row }">
					{{ !row.isDir && row.size ? formatFileSize(row.size) : '' }}
				</template>
			</el-table-column>
			<el-table-column prop="modTime" label="修改时间" width="180">
				<template #default="{ row }">{{ $validators.formatDate(row.modTime) }}</template>
			</el-table-column>
			<el-table-column label="操作" width="170" fixed="right">
				<template #default="{ row }">
					<el-dropdown trigger="click" @command="handleCommand($event, row)">
						<el-button type="primary" link>
							操作<el-icon><arrow-down /></el-icon>
						</el-button>
						<template #dropdown>
							<el-dropdown-menu>
							    <el-dropdown-item v-if="!row.isDir" command="share">分享</el-dropdown-item>
								<el-dropdown-item command="rename">重命名</el-dropdown-item>
								<el-dropdown-item command="copy">复制</el-dropdown-item>
								<el-dropdown-item command="move">移动</el-dropdown-item>
								<el-dropdown-item v-if="row.isDir" command="zip">压缩</el-dropdown-item>
								<el-dropdown-item v-if="isZipFile(row)" command="unzip">解压</el-dropdown-item>
								<el-dropdown-item divided command="delete">删除</el-dropdown-item>
							</el-dropdown-menu>
						</template>
					</el-dropdown>
				</template>
			</el-table-column>
		</el-table>

		<!-- 分页 -->
		<div class="pagination-wrapper">
			<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :total="total"
				:page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper"
				@current-change="loadFiles" @size-change="loadFiles" background />
		</div>

		<el-dialog v-model="previewVisible" :title="textEditDialog.file?.name" top="5vh" destroy-on-close>
            <template #header>
                <div style="display: flex;align-items: center;gap: 12px;">
                    <span>{{ textEditDialog.file?.name }}</span>
                    <template v-if="isEditable(textEditDialog.file?.ext)">
                        <el-button type="primary" link @click="textEditDialog.isedit=!textEditDialog.isedit" style="margin-left:auto;">
                            <el-icon size="18"><Edit /></el-icon>
                            <span style="font-size: 15px;">{{ textEditDialog.isedit ? '预览' : '编辑' }}</span>
                        </el-button>
                    </template>
                </div>
            </template>
			<!-- 媒体预览 -->
			<div v-if="['jpg', 'jpeg', 'png', 'gif', 'mp4'].includes(textEditDialog.file?.ext)" class="preview-media">
				<img v-if="['jpg', 'jpeg', 'png', 'gif'].includes(textEditDialog.file?.ext)" :src="textEditDialog.content" class="preview-image">
				<video v-else controls autoplay :src="textEditDialog.content" class="preview-player"></video>
			</div>

			<!-- 文本预览 -->
            <div class="preview-text" v-if="isEditable(textEditDialog.file?.ext)">
                <el-scrollbar height="70vh">
                    <el-input v-if="textEditDialog.isedit" v-model="textEditDialog.content" type="textarea" :autosize="{ minRows: 30 }" placeholder="输入文本内容..." resize="none" class="editor-textarea" />
                    <article class="text-content" v-else>
                        <pre v-if="textEditDialog.file?.ext === 'txt'" v-html="formatTextContent(textEditDialog.content)"></pre>
                        <div v-else v-html="highlightCode(textEditDialog.content, textEditDialog.file?.ext)" :class="'language-' + textEditDialog.file?.ext">
                        </div>
                    </article>
                </el-scrollbar>
            </div>

			<!-- PDF预览 -->
			<div v-if="textEditDialog.file?.ext === 'pdf'" class="preview-pdf">
				<iframe :src="textEditDialog.content" width="100%" height="600" frameborder="0"></iframe>
			</div>

			<template #footer>
			    <el-button v-if="textEditDialog.isedit" type="primary" @click="handleSaveText">保存</el-button>
				<el-button @click="previewVisible = false">关闭</el-button>
			</template>
		</el-dialog>

		<!-- 文件操作对话框 -->
		<fileoperation v-model="operationDialog.visible" :type="operationDialog.type" :file="operationDialog.file"
			:current-path="currentPath" @confirm="handleOperationConfirm" />

		<!-- 上传对话框 -->
		<UploadDialog v-model="showUploadDialog" :current-path="currentPath" @success="handleUploadSuccess" />
		
        <!-- 分享二维码 -->
        <el-dialog v-model="qrDialogVisible" width="500px">
            <div style="display: grid;grid-template-rows: auto auto;justify-items: center;row-gap: 24px;">
                <div><h2>手机扫码查看</h2></div>
                <qrcode-vue :value="ewmurl" :size="300"/>
                <div style="line-height:2em;">
                    <div style="text-align:center;">
                        <el-button type="success" @click="copyCode()">复制链接</el-button>
                    </div>
                </div>
            </div>
        </el-dialog>
	</div>
    `
}